<script setup>
import { onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import FullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import { Plus, Download, Upload, RefreshRight } from '@element-plus/icons-vue'
import vModal from '@/components/modal/index.vue'
import ParkList from '@/components/parkList/index.vue'
import moment from 'moment'
import { parkPageList } from '@/api/manager/dataManage/park'
import {
  getUserList,
  getDepartmentPersonTree,
} from '@/api/manager/systemManage/user.js'
import {
  getHolidayList,
  updateHoliday,
  getScheduleList,
  addSchedule,
  deleteSchedule,
  importSchedule,
  exportSchedule,
} from '@/api/manager/inspectionManage/personSchedule.js'

const fullCalendarRef = ref()
// 日历配置
const calendarOptions = ref({
  plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin],
  initialView: 'dayGridMonth',
  locale: 'zh-cn',
  height: '720px',
  headerToolbar: {
    start: '',
    center: 'title,prev,next',
    end: 'today dayGridMonth',
  },
  buttonText: {
    today: '今天',
    month: '月',
  },
  customButtons: {
    prevMonthCustom: {
      text: '上月',
      click: (e) => {
        prevMonthCustomClick(e)
      },
    },
    nextMonthCustom: {
      text: '下月',
      click: (e) => {
        nextMonthCustomClick()
      },
    },
  },
  headerToolbar: {
    left: '',
    center: 'title',
    right: 'today,prevMonthCustom,nextMonthCustom',
  },
  allDayText: '全天',
  firstDay: 1,
  selectable: true,
  events: [
    // {
    //   title: '9:00-17:30【张建国】',
    //   id: 1,
    //   username: '张建国',
    //   workDate: '9:00-17:30',
    //   remark: '无',
    //   start: new Date().toISOString().split('T')[0],
    //   ustart: '2024-03-08',
    //   uend: '2024-03-08',
    //   color: '#eaf6fe',
    //   textColor: '#3a79eb',
    // },
  ],
  views: {
    //对应月视图
    dayGridMonth: {
      dayCellContent(item) {
        const date = item.date
        const day = date.getDate()
        return { html: day }
      },
    },
  },
  dateClick: function (info) {
    const hasAfter = showEditAndDelete(info.dateStr)
    if (hasAfter) {
      handleAdd(info.dateStr)
    }
  },
})
// 日历切换：上月
const prevMonthCustomClick = (e) => {
  fullCalendarRef.value.getApi().prev()
  renderCalendar()
}
// 日历切换：下月
const nextMonthCustomClick = () => {
  fullCalendarRef.value.getApi().next()
  renderCalendar()
}

// 切换园区
const areaId = ref('')
const handleChangePark = (val) => {
  const isFlashHoliday = !areaId.value
  areaId.value = val
  renderCalendar(isFlashHoliday)
}
// 查询节假日和排班人员
const holidayList = ref([])
const scheduleList = ref([])
const renderCalendar = async (isFlashHoliday = true) => {
  const currentData =
    fullCalendarRef.value.calendar.currentData.dateProfile.currentDate
  const year = moment(currentData).format('YYYY-MM')
  if (isFlashHoliday) {
    await getHoliday(year)
  }
  await getSchedule(year)
  calendarOptions.value.events = [...holidayList.value, ...scheduleList.value]
}
// 查询年月节假日
const getHoliday = async (day) => {
  const res = await getHolidayList({
    yearMonth: day,
  })
  if (res.success) {
    const holidays = []
    res.data.forEach((data) => {
      const supplementDayArr = data.supplementDay
        ? data.supplementDay.split('|')
        : []
      const vacationArr = data.vacation ? data.vacation.split('|') : []
      supplementDayArr.forEach((item) => {
        holidays.push({
          title: '班',
          start: item,
          display: 'background',
          className: 'work-item',
        })
      })
      vacationArr.forEach((item) => {
        holidays.push({
          title: '假',
          start: item,
          display: 'background',
          className: 'holiday-item',
        })
      })
    })
    holidayList.value = holidays
  } else {
    ElMessage.error(res.message)
  }
}
// 查询年月排班
const getSchedule = async (day) => {
  const res = await getScheduleList({ yearMonth: day, areaId: areaId.value })
  const schedules = []
  res.data.forEach((item) => {
    schedules.push({
      title: `负责人：${item.dutyName || ''}`,
      start: item.date,
      color: '#eaf6fe',
      textColor: '#3a79eb',
      ...item,
    })
    schedules.push({
      title: `白班：${item.dayShiftName || ''}`,
      start: item.date,
      color: '#eaf6fe',
      textColor: '#3a79eb',
      ...item,
    })
    schedules.push({
      title: `夜班：${item.nightShiftName || ''}`,
      start: item.date,
      color: '#eaf6fe',
      textColor: '#3a79eb',
      ...item,
    })
  })
  scheduleList.value = schedules
}
// 更新节假日
const handleUpdateHoliday = async () => {
  const currentData =
    fullCalendarRef.value.calendar.currentData.dateProfile.currentDate
  const year = moment(currentData).format('YYYY')
  ElMessageBox.confirm(`是否确定更新${year}年节假日`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(async () => {
      const res = await updateHoliday({
        year: year,
      })
      if (res.success) {
        ElMessage.success('更新成功')
      } else {
        ElMessage.error(res.message)
      }
    })
    .catch((err) => {
      console.log(err)
    })
}
// 导入
const handleImport = async (param) => {
  const formData = new FormData()
  formData.append('file', param.file)
  const res = await importSchedule(formData)
  if (res.success) {
    ElMessage.success(res.message)
    renderCalendar(false)
  } else {
    ElMessage.error(res.message)
  }
}
// 导出
const handleExport = async () => {
  const currentData =
    fullCalendarRef.value.calendar.currentData.dateProfile.currentDate
  const yearMonth = moment(currentData).format('YYYY-MM')
  const res = await exportSchedule()
  let blobUrl = window.URL.createObjectURL(
    new Blob([res], {
      type: 'application/excel',
    }),
  )
  let fileName = `人员排班导入模版.xlsx`
  const link = document.createElement('a')
  link.style.display = 'none'
  link.href = blobUrl
  link.setAttribute('download', fileName)
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

const formRef = ref()
const form = ref({})
const rules = ref({
  date: [{ required: true, message: '请选择日期', trigger: 'blur' }],
  dutyId: [{ required: true, message: '请选择值班负责人', trigger: 'blur' }],
  dayShift: [{ required: true, message: '请选择白班人员', trigger: 'blur' }],
  areaId: [{ required: true, message: '请选择片区', trigger: 'blur' }],
})
const formVisible = ref(false)
// 新增
const handleAdd = (date) => {
  initInspectorList()
  initSltzList()
  initFgsList()
  form.value = {
    areaId: areaId.value,
    date: date || moment().format('YYYY-MM-DD'),
    dayShift: [],
    nightShift: [],
  }
  formVisible.value = true
}
// 编辑
const handleEdit = (info) => {
  initInspectorList()
  initSltzList()
  initFgsList()
  const detail = {
    ...info.extendedProps,
    date: moment(info.start).format('YYYY-MM-DD'),
  }
  detail.dayShift = detail.dayShift ? detail.dayShift.split(',') : []
  detail.nightShift = detail.nightShift ? detail.nightShift.split(',') : []
  form.value = detail
  formVisible.value = true
}
// 删除
const handleDelete = (row) => {
  ElMessageBox.confirm('是否确定删除该项？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(async () => {
      const params = { pkid: row.pkid }
      const res = await deleteSchedule(params)
      if (res.success) {
        ElMessage({
          type: 'success',
          message: '删除成功',
        })
        renderCalendar(false)
      } else {
        ElMessage.error(res.message)
      }
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '已取消删除',
      })
    })
}
// 提交表单
const handleSubmit = async () => {
  if (!formRef.value) return
  await formRef.value.validate(async (valid, fields) => {
    if (valid) {
      try {
        const params = JSON.parse(JSON.stringify(form.value))
        params.dayShift = params.dayShift.length
          ? params.dayShift.join(',')
          : ''
        params.nightShift = params.nightShift.length
          ? params.nightShift.join(',')
          : ''
        let res = await addSchedule(params)
        if (res.success) {
          ElMessage.success('保存成功')
          handleClose(true)
        } else {
          ElMessage.error(res.message)
        }
      } catch (error) {
        console.log('error', error)
      }
    } else {
      ElMessage.warning('请正确录入信息')
    }
  })
}
// 关闭弹窗
const handleClose = (isFlash) => {
  form.value = {}
  formRef.value.clearValidate()
  formVisible.value = false
  if (isFlash) {
    renderCalendar(false)
  }
}
// 获取园区列表
const parkOptions = ref([])
const initParkOptions = async () => {
  const res = await parkPageList({
    pageIndex: 1,
    pageSize: 9999,
    enable: '1',
    hasHidden: 1,
  })
  parkOptions.value = res.data.list
}
// 获取四联投资人员: 单位-资产分公司，部门-公司领导
const sltzList = ref([])
const initSltzList = async () => {
  const res = await getUserList({
    pageIndex: 1,
    pageSize: 9999,
    userState: 1,
    unitId: '10501',
    deptId: '9',
  })
  sltzList.value = res.data.list
}

// 获取分公司人员
const cascaderProps = ref({
  value: 'pkid',
  label: 'deptName',
  children: 'childTree',
})
const fgsList = ref([])
const initFgsList = async () => {
  const res = await getDepartmentPersonTree({
    unitId: '10501',
    deptId: '10,11,19,20',
  })
  res.data.forEach((item) => {
    fgsList.value = fgsList.value.concat(item.coreUserInfos)
  })
  // fgsList.value = res.data
}

// 获取检查人员
const inspectorList = ref([])
const initInspectorList = async () => {
  const res = await getUserList({
    pageIndex: 1,
    pageSize: 9999,
    isPatrol: 1,
    userState: 1,
    areaId: [areaId.value],
  })
  inspectorList.value = res.data.list
}

const showEditAndDelete = (date) => {
  if (moment().format('YYYY-MM-DD') === moment(date).format('YYYY-MM-DD')) {
    return true
  } else {
    const currentTime = moment()
    const someFutureTime = moment(date)
    const hasPassed = someFutureTime.isAfter(currentTime)
    return hasPassed
  }
}
const disabledDate = (time) => {
  return time.getTime() < Date.now() - 8.64e7
}
onMounted(() => {
  initParkOptions()
})
</script>

<template>
  <div class="person-schedule-wrapper">
    <ParkList @change="handleChangePark" :hasHidden="1" :hasReset="false" />
    <div class="right">
      <div class="custom-full-calendar-btns">
        <el-button type="primary" @click="handleAdd()">
          <el-icon>
            <Plus />
          </el-icon>
          <span>新增排班</span>
        </el-button>
        <el-upload
          class="custom-upload"
          ref="uploadRef"
          :show-file-list="false"
          action="#"
          :http-request="handleImport"
          accept=".xls,.xlsx"
        >
          <el-button type="primary">
            <el-icon><Upload /></el-icon>
            <span>导入</span>
          </el-button>
        </el-upload>
        <el-button type="primary" @click="handleExport">
          <el-icon>
            <Download />
          </el-icon>
          <span>模版下载</span>
        </el-button>
        <el-button type="primary" @click="handleUpdateHoliday">
          <el-icon><RefreshRight /></el-icon>
          <span>更新节假日</span>
        </el-button>
        <div class="tips">
          <!-- 说明：点击单元格空白处，可添加排班；单击单条排班可编辑和删除。 -->
        </div>
      </div>
      <FullCalendar ref="fullCalendarRef" :options="calendarOptions">
        <template v-slot:eventContent="{ event }">
          <el-popover placement="right" :width="300" trigger="click">
            <template #reference>
              <div class="fc-event-item">{{ event.title }}</div>
            </template>
            <div class="event-data-popover">
              <div class="detail-item">
                <span class="label">带班领导:</span>
                <span class="value">{{ event.extendedProps.leaderName }}</span>
              </div>
              <div class="detail-item">
                <span class="label">值班中干:</span>
                <span class="value">{{
                  event.extendedProps.middleDutyName
                }}</span>
              </div>
              <div class="detail-item">
                <span class="label">负责人:</span>
                <span class="value">{{ event.extendedProps.dutyName }}</span>
              </div>
              <div class="detail-item">
                <span class="label">白班:</span>
                <span class="value">{{
                  event.extendedProps.dayShiftName
                }}</span>
              </div>
              <div class="detail-item">
                <span class="label">夜班:</span>
                <span class="value">{{
                  event.extendedProps.nightShiftName
                }}</span>
              </div>
              <div class="detail-item" v-if="showEditAndDelete(event.start)">
                <el-button
                  class="btn"
                  type="primary"
                  size="small"
                  @click="handleEdit(event)"
                  >编辑</el-button
                >
                <el-button
                  class="btn"
                  type="danger"
                  size="small"
                  @click="handleDelete(event.extendedProps)"
                  >删除</el-button
                >
              </div>
            </div>
          </el-popover>
        </template>
      </FullCalendar>
    </div>
    <!-- 新增/编辑表单 -->
    <v-modal
      class="custom-modal"
      title="新增排班"
      v-model:visible="formVisible"
      width="500px"
      @ok="handleSubmit"
      @close="handleClose"
    >
      <div class="scheduling-form-wrapper">
        <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
          <el-form-item label="日期" prop="date">
            <el-date-picker
              class="data-input"
              v-model="form.date"
              type="date"
              value-format="YYYY-MM-DD"
              placeholder="请选择"
              :disabled-date="disabledDate"
            ></el-date-picker>
          </el-form-item>
          <el-form-item label="片区" prop="areaId">
            <el-select v-model="form.areaId" placeholder="请选择" disabled>
              <el-option
                v-for="item in parkOptions"
                :key="item.pkid"
                :label="item.name"
                :value="item.pkid"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="带班领导" prop="name">
            <el-select
              v-model="form.leaderId"
              placeholder="请选择"
              clearable
              filterable
            >
              <el-option
                v-for="item in sltzList"
                :key="item.pkid"
                :label="item.userName"
                :value="item.pkid"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="值班中干" prop="middleDutyId">
            <el-select
              v-model="form.middleDutyId"
              placeholder="请选择"
              clearable
              filterable
            >
              <el-option
                v-for="item in fgsList"
                :key="item.pkid"
                :label="item.userName"
                :value="item.pkid"
              ></el-option>
            </el-select>
            <!-- <el-cascader
              v-model="form.middleDutyId"
              placeholder="请选择"
              clearable
              :options="fgsList"
              :show-all-levels="false"
              :props="cascaderProps"
            /> -->
          </el-form-item>
          <el-form-item label="值班负责人" prop="dutyId">
            <el-select v-model="form.dutyId" placeholder="请选择">
              <el-option
                v-for="item in inspectorList"
                :key="item.pkid"
                :label="item.userName"
                :value="item.pkid"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="白班" prop="dayShift">
            <el-select v-model="form.dayShift" placeholder="请选择" multiple>
              <el-option
                v-for="item in inspectorList"
                :key="item.pkid"
                :label="item.userName"
                :value="item.pkid"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="夜班" prop="nightShift">
            <el-select
              v-model="form.nightShift"
              placeholder="请选择"
              multiple
              clearable
            >
              <el-option
                v-for="item in inspectorList"
                :key="item.pkid"
                :label="item.userName"
                :value="item.pkid"
              ></el-option>
            </el-select>
          </el-form-item>
        </el-form>
      </div>
    </v-modal>
  </div>
</template>

<style lang="scss" scoped>
.person-schedule-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;

  .custom-full-calendar-btns {
    display: flex;
    align-items: center;
    z-index: 1;

    .tips {
      margin-left: 20px;
      font-size: 12px;
      color: #666;
    }
    .custom-upload {
      margin: 0 10px;
    }
  }

  .right {
    flex: 1;
    background-color: #ffffff;
    box-shadow: 0px 0px 10px 0px rgba(72, 121, 238, 0.1);
    border-radius: 4px;
    box-sizing: border-box;
    padding: 20px;
  }
}

.scheduling-form-wrapper {
  padding: 20px;
  width: 100%;

  .el-form-item {
    margin-bottom: 20px;

    .el-select,
    .el-date-picker,
    .el-time-picker,
    .el-input {
      width: 100%;
    }
  }
}
</style>

<style lang="scss">
.event-data-popover {
  position: relative;
  .detail-item {
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    margin-bottom: 20px;
    &:last-child {
      margin-bottom: 0;
    }
  }
  .label {
    font-size: 14px;
    line-height: 16px;
    font-weight: 400;
    color: #333333;
    display: inline-block;
    margin-right: 10px;
    text-align: right;
  }
  .value {
    flex: 1;
    display: inline-block;
    font-size: 14px;
    line-height: 16px;
    font-weight: 400;
    color: #757575;
  }
  .btn {
    width: calc(50% - 6px);
  }
}

.person-schedule-wrapper {
  .fc .fc-daygrid-day.fc-day-today {
    position: relative;
    background-color: transparent;

    .fc-daygrid-day-number {
      color: #fff;
      background-color: #3a79eb;
    }
  }

  .fc-daygrid-day-events {
    margin-top: 5px;
  }

  .fc-event-item {
    cursor: pointer;

    &:hover {
      background: #dde7ee;
    }
  }

  .fc-daygrid-day-top {
    display: flex;
    justify-content: flex-end;
  }

  .fc-daygrid-day-number {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    font-size: 12px;
    overflow: hidden;
    text-overflow: clip;
    white-space: nowrap;
    border-radius: 50%;
  }

  .fc-header-toolbar {
    position: relative;

    .fc-toolbar-title {
      font-size: 14px;
    }

    .fc-button {
      cursor: pointer;
      padding: 1px 10px;
      color: #000;
      background: #f7f7f7;
      border: none;
      font-size: 14px;
      box-shadow: none !important;

      &:hover,
      &:active,
      &:focus {
        color: #000 !important;
        background: #f0f0f0 !important;
        border: none !important;
        outline: none !important;
      }
    }

    .fc-button-active {
      color: #fff;
      background: #3a79eb !important;
      border: none;

      &:hover,
      &:active,
      &:focus {
        color: #fff !important;
        background: #3a79eb !important;
        border: none !important;
        outline: none !important;
      }
    }

    .fc-today-button {
      &:disabled {
        color: #000;
        background: #f7f7f7;
        border: none;
        cursor: not-allowed;

        &:hover,
        &:active,
        &:focus {
          color: #000 !important;
          background: #f7f7f7 !important;
          border: none !important;
          outline: none !important;
        }
      }
    }

    .fc-prev-button {
      position: absolute;
      left: 55%;
      top: -2px;
      transform: translateX(-50%);
    }

    .fc-next-button {
      position: absolute;
      left: center;
      left: 58%;
      top: -2px;
      transform: translateX(-50%);
    }
  }

  .fc-daygrid-event-harness {
    padding: 5px 0;
    letter-spacing: 1px;
  }

  .holiday-item {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #d3d7da;
    border: none;
    font-size: 12px;
    line-height: 12px;
    font-weight: 400;
    color: #fff;
    position: absolute;
    top: 2px;
    left: 25px;
    opacity: 1;
  }
  .work-item {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #3a79eb !important;
    border: none;
    font-size: 12px;
    line-height: 12px;
    font-weight: 400;
    color: #fff;
    position: absolute;
    top: 2px;
    left: 25px;
    opacity: 1;
  }
  .fc .fc-daygrid-day-frame {
    height: 120px;
    position: relative;
  }
}
</style>
